package com.ipc.app.service.impl;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import com.ipc.app.dal.dao.OrderDAO;
import com.ipc.app.dal.doObject.OrderDO;
import com.ipc.app.model.Order;
import com.ipc.app.model.Paginator;
import com.ipc.app.service.OrderService;
import com.ipc.app.util.converter.OrderConverter;
import com.ipc.app.util.id.IDGenerator;

/**
 * @author 雪
 * 
 */
public class OrderServiceImpl implements OrderService {

	private OrderDAO orderDAO;

	private TransactionTemplate transactionTemplate;

	public String createOrder(final Order order) {
		transactionTemplate
				.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);
		String orderId = (String) transactionTemplate
				.execute(new TransactionCallback() {
					public Object doInTransaction(TransactionStatus arg0) {
						String orderID = IDGenerator.idGeneration();
						OrderDO orderDO = OrderConverter.orderCoreTODO(order);
						orderDO.setOrderId(orderID);
						orderDAO.createOrder(orderDO);
						return orderID;
					}
				});
		return orderId;
	}

	public Order lockOrder(final String orderID) {
		transactionTemplate
				.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_MANDATORY);
		Order order = (Order) transactionTemplate
				.execute(new TransactionCallback() {
					public Object doInTransaction(TransactionStatus arg0) {
						OrderDO orderDO = orderDAO.getOrderAndLock(orderID);
						Order order = OrderConverter.orderDOTOCore(orderDO);
						return order;
					}
				});
		return order;
	}

	public Order getOrderByID(String orderID) {
		OrderDO orderDO = orderDAO.getOrder(orderID);
		Order order = OrderConverter.orderDOTOCore(orderDO);
		return order;
	}

	public void updateOrder(final Order order) {
		transactionTemplate
				.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);
		transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus arg0) {
				OrderDO orderDO = OrderConverter.orderCoreTODO(order);
				orderDAO.updateOrder(orderDO);
			}

		});
	}

	public void setOrderDAO(OrderDAO orderDAO) {
		this.orderDAO = orderDAO;
	}

	public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
		this.transactionTemplate = transactionTemplate;
	}

	public List<Order> getExpiredOrder(Date date) {
		List<OrderDO> orderDOs = orderDAO.getExpiredOrder(date);
		if (null == orderDOs) {
			return null;
		}
		List<Order> orders = new LinkedList<Order>();
		for (OrderDO orderDO : orderDOs) {
			Order order = OrderConverter.orderDOTOCore(orderDO);
			orders.add(order);
		}
		return orders;
	}

	public Paginator<Order> getOrderByUserID(String userID, int pageIndex) {
		int orderItems = orderDAO.getOrderCountByUser(userID);
		Paginator<Order> pOrders = new Paginator<Order>();
		if (orderItems > 0) {
			List<OrderDO> orderDOs = orderDAO.getOrderByUser(userID,
					Paginator.DEFAULT_ITEMS_PER_PAGE, pageIndex);
			List<Order> orders = new LinkedList<Order>();
			if (null != orderDOs && orderDOs.size() > 0) {
				for (OrderDO orderDO : orderDOs) {
					Order order = OrderConverter.orderDOTOCore(orderDO);
					orders.add(order);
				}
			}
			pOrders.setPage(pageIndex);
			pOrders.setItems(orderItems);
			pOrders.setObject(orders);
		}
		return pOrders;
	}
}
